﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Waiter.Common;
using DevComponents.DotNetBar.Controls;
using Waiter.DataLayer;

namespace Waiter.Controler
{
    class ReportSalaryCtrl
    {
        /// <summary>
        /// Trả về danh sách lương nhân viên
        /// </summary>
        /// <param name="pStartDate">Thời điểm bắt đầu tra cứu</param>
        /// <param name="pEndDate">Thời điểm kết thúc tra cứu</param>
        /// <param name="pStaffCode">Code nhân viên (nếu tính toán tất cả nhân viên thì truyền vào String.Emtpy)</param>
        /// <returns></returns>
        public List<VIEW_Salary> fsLoadListSalary(DateTime pStartDate, DateTime pEndDate, string pStaffCode)
        {
            List<SALARY> myListSalary = new List<SALARY>();
            List<VIEW_Salary> myViewSalary = new List<VIEW_Salary>();

            try
            {
                //Tính toán lương nhân viên
                if (pStaffCode == string.Empty)
                {
                    //Tinh luong tat ca nhan vien
                    //Load thông tin của tất cả nhân viên cần tính lương (loại trừ các nhân viên được setting là không tính.
                    List<STAFF> myStaffListToCalcSalary = CommonGlobalVariable.globalDataContext.STAFFs.Where(x => x.IS_SALARY_MANAGEMENT == true & x.DEL_FLG == false).ToList();

                    //Kiểm bắt đầu tính lương cho từng nhân viên
                    long nUniqueCode = Convert.ToInt64(String.Format(CommonConstants.CODE_DATE, DateTime.Now));//Key code của table (vì lấy thông tin theo ngày giờ, tính nhanh quá sẽ bị trùng khóa chính).
                    foreach (var staff in myStaffListToCalcSalary)
                    {
                        //Lấy thông tin chấm công của từng nhân viên
                        List<HOURS_WORKED> myHoursWorkedList = CommonGlobalVariable.globalDataContext.HOURS_WORKEDs.Where(x => x.STAFF_CODE == staff.CODE & x.CREATE_DATE >= pStartDate & x.CREATE_DATE <= pEndDate).ToList();

                        if (myHoursWorkedList != null && myHoursWorkedList.Count > 0)
                        {
                            //Nếu có thông tin chấm công
                            //Tính toán lương
                            double nTotalTimeWorked = myHoursWorkedList.Sum(x => x.TIME_LENGHT);//Tổng số giờ làm việc trong tháng.
                            double nPayMoney = nTotalTimeWorked * staff.UNIT_SALARY;//Tổng số lương tính được

                            //Save thông tin lương sau khi tính
                            SALARY mySalaryInsertData = new SALARY();
                            mySalaryInsertData.CODE = (++nUniqueCode).ToString();
                            mySalaryInsertData.STAFF_CODE = staff.CODE;
                            mySalaryInsertData.IS_FIRST_PAY = true;
                            mySalaryInsertData.MONTH_OUTPUT = DateTime.Now;
                            mySalaryInsertData.TOTAL_TIME_WORKED = nTotalTimeWorked;
                            mySalaryInsertData.UNIT_SALARY = staff.UNIT_SALARY;
                            mySalaryInsertData.PAY_SALARY = (long)nPayMoney;
                            mySalaryInsertData.TOTAL_PAY_SALARY = (long)nPayMoney;
                            mySalaryInsertData.IS_PAID = false;
                            mySalaryInsertData.PAY_DATE = DateTime.MaxValue;
                            mySalaryInsertData.OPID = "";
                            mySalaryInsertData.ADD_DATE = DateTime.Now;
                            mySalaryInsertData.UPD_DATE = DateTime.Now;

                            myListSalary.Add(mySalaryInsertData);
                        }
                        else
                        {
                            //Nếu không có thông tin chấm công
                            //Lưu thông tin lương với số tiền = 0
                            SALARY mySalaryInsertData = new SALARY();
                            mySalaryInsertData.CODE = (++nUniqueCode).ToString();
                            mySalaryInsertData.STAFF_CODE = staff.CODE;
                            mySalaryInsertData.IS_FIRST_PAY = true;
                            mySalaryInsertData.MONTH_OUTPUT = DateTime.Now;
                            mySalaryInsertData.TOTAL_TIME_WORKED = 0;
                            mySalaryInsertData.UNIT_SALARY = staff.UNIT_SALARY;
                            mySalaryInsertData.PAY_SALARY = 0;
                            mySalaryInsertData.TOTAL_PAY_SALARY = 0;
                            mySalaryInsertData.IS_PAID = false;
                            mySalaryInsertData.PAY_DATE = DateTime.MaxValue;
                            mySalaryInsertData.OPID = "";
                            mySalaryInsertData.ADD_DATE = DateTime.Now;
                            mySalaryInsertData.UPD_DATE = DateTime.Now;

                            myListSalary.Add(mySalaryInsertData);
                        }
                    }

                }
                else
                {
                    //Tinh luong cho 1 nhan vien
                    //Lấy thông tin nhân viên
                    STAFF myStaff = CommonGlobalVariable.globalDataContext.STAFFs.SingleOrDefault(x => x.CODE == pStaffCode);

                    //Lấy thông tin chấm công
                    List<HOURS_WORKED> myHoursWorkedList = CommonGlobalVariable.globalDataContext.HOURS_WORKEDs.Where(x => x.STAFF_CODE == pStaffCode & x.CREATE_DATE >= pStartDate & x.CREATE_DATE <= pEndDate).ToList();

                    if (myHoursWorkedList != null && myHoursWorkedList.Count > 0)
                    {
                        //Có thông tin chấm công

                        //Tính toán lương
                        double nTotalTimeWorked = myHoursWorkedList.Sum(x => x.TIME_LENGHT);//Tổng số giờ làm việc trong tháng.
                        double nPayMoney = nTotalTimeWorked * myStaff.UNIT_SALARY;//Tổng số lương tính được

                        //Save thông tin lương sau khi tính
                        SALARY mySalaryInsertData = new SALARY();
                        mySalaryInsertData.CODE = String.Format(CommonConstants.CODE_DATE, DateTime.Now);
                        mySalaryInsertData.STAFF_CODE = pStaffCode;
                        mySalaryInsertData.IS_FIRST_PAY = true;
                        mySalaryInsertData.MONTH_OUTPUT = DateTime.Now;
                        mySalaryInsertData.TOTAL_TIME_WORKED = nTotalTimeWorked;
                        mySalaryInsertData.UNIT_SALARY = myStaff.UNIT_SALARY;
                        mySalaryInsertData.PAY_SALARY = (long)nPayMoney;
                        mySalaryInsertData.TOTAL_PAY_SALARY = (long)nPayMoney;
                        mySalaryInsertData.IS_PAID = false;
                        mySalaryInsertData.PAY_DATE = DateTime.MaxValue;
                        mySalaryInsertData.OPID = "";
                        mySalaryInsertData.ADD_DATE = DateTime.Now;
                        mySalaryInsertData.UPD_DATE = DateTime.Now;

                        myListSalary.Add(mySalaryInsertData);
                    }
                    else
                    {
                        //Không có thông tin chấm công
                        //Lưu thông tin với lương = 0
                        SALARY mySalaryInsertData = new SALARY();
                        mySalaryInsertData.CODE = String.Format(CommonConstants.CODE_DATE, DateTime.Now);
                        mySalaryInsertData.STAFF_CODE = pStaffCode;
                        mySalaryInsertData.IS_FIRST_PAY = true;
                        mySalaryInsertData.MONTH_OUTPUT = DateTime.Now;
                        mySalaryInsertData.TOTAL_TIME_WORKED = 0;
                        mySalaryInsertData.UNIT_SALARY = myStaff.UNIT_SALARY;
                        mySalaryInsertData.PAY_SALARY = 0;
                        mySalaryInsertData.TOTAL_PAY_SALARY = 0;
                        mySalaryInsertData.IS_PAID = false;
                        mySalaryInsertData.PAY_DATE = DateTime.MaxValue;
                        mySalaryInsertData.OPID = "";
                        mySalaryInsertData.ADD_DATE = DateTime.Now;
                        mySalaryInsertData.UPD_DATE = DateTime.Now;

                        myListSalary.Add(mySalaryInsertData);
                    }   
                }

                //Thay đổi số tiền lương (nếu có) - và chuyển thành format để output lên grid
                foreach (var item in myListSalary)
                {
                    VIEW_Salary myInsertViewSalary = new VIEW_Salary();
                    myInsertViewSalary.strSALARY_CODE = item.CODE;                                                                                                                        //Key code
                    myInsertViewSalary.strSTAFF_CODE = item.STAFF_CODE;                                                                                                                   //Code nhân viên
                    myInsertViewSalary.strSTAFF_NAME = CommonGlobalVariable.globalDataContext.STAFFs.SingleOrDefault(x => x.CODE == item.STAFF_CODE).NAME; //item.STAFF.NAME;             //Code nhân viên
                    myInsertViewSalary.bIS_FRIST_PAY = item.IS_FIRST_PAY;                                                                                                                 //Code kỳ tính lương
                    myInsertViewSalary.strFRIST_PAY = item.IS_FIRST_PAY == true ? "Đầu tháng" : "Cuối tháng";                                                                             //Tên kỳ tính lương
                    myInsertViewSalary.dateMONTH_OUTPUT = item.MONTH_OUTPUT;                                                                                                              //Tháng/năm tính lương
                    myInsertViewSalary.iTOTAL_TIME_WORKDED = item.TOTAL_TIME_WORKED;                                                                                                      //Số giờ làm việc trong tháng
                    myInsertViewSalary.iUNIT_SALARY = item.UNIT_SALARY;                                                                                                                   //Lương đơn vị
                    myInsertViewSalary.iPAY_SALARY = item.PAY_SALARY;                                                                                                                     //Số tiền lương (tính theo giờ công)
                    myInsertViewSalary.iTOTAL_PAY_SALARY = item.TOTAL_PAY_SALARY;                                                                                                         //Số tiền lương phải trả (đã có điều chỉnh)
                    myInsertViewSalary.bIS_PAID = item.IS_PAID;                                                                                                                           //Đã chi trả lương hay chưa
                    myInsertViewSalary.datePAY_DATE = item.PAY_DATE;                                                                                                                      //Ngày chi trả lương
                    try
                    {
                        myInsertViewSalary.strSALARY_CHANGE_CODE = CommonGlobalVariable.globalDataContext.SALARY_CHANGEs.SingleOrDefault(x => x.SALARY_CODE == item.CODE).CODE;           //Key code
                    }
                    catch (Exception ex)
                    {
                        CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR,
                            "ReportSalaryCtrl.fsLoadListSalary strSALARY_CHANGE_CODE",
                            CommonUtils.fsParamListToString(new object[3] { pStartDate, pEndDate, pStaffCode}),
                            ex.ToString());
                        myInsertViewSalary.strSALARY_CHANGE_CODE = string.Empty;
                    }
                    try
                    {
                        myInsertViewSalary.nSALARY_CHANGE_AMOUNT = CommonGlobalVariable.globalDataContext.SALARY_CHANGEs.SingleOrDefault(x => x.SALARY_CODE == item.CODE).AMOUNT;             //Số tiền lương thay đổi
                    }
                    catch (Exception ex)
                    {
                        CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR,
                            "ReportSalaryCtrl.fsLoadListSalary nSALARY_CHANGE_AMOUNT",
                            CommonUtils.fsParamListToString(new object[3] { pStartDate, pEndDate, pStaffCode }),
                            ex.ToString());
                        myInsertViewSalary.nSALARY_CHANGE_AMOUNT = 0;
                    }
                    try
                    {
                        myInsertViewSalary.strSALARY_CHANGE_NOTE = CommonGlobalVariable.globalDataContext.SALARY_CHANGEs.SingleOrDefault(x => x.SALARY_CODE == item.CODE).NOTE;               //Ghi chú về thay đổi lương
                    }
                    catch (Exception ex)
                    {
                        CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR,
                           "ReportSalaryCtrl.fsLoadListSalary strSALARY_CHANGE_NOTE",
                           CommonUtils.fsParamListToString(new object[3] { pStartDate, pEndDate, pStaffCode }),
                           ex.ToString());
                        myInsertViewSalary.strSALARY_CHANGE_NOTE = string.Empty;
                    }
                    

                    myViewSalary.Add(myInsertViewSalary);
                }

                //Sort lại data
                myViewSalary = myViewSalary.OrderBy(x => x.strSTAFF_NAME).ToList();

            }
            catch (Exception ex)
            {
                CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR,
                           "ReportSalaryCtrl.fsLoadListSalary",
                           CommonUtils.fsParamListToString(new object[3] { pStartDate, pEndDate, pStaffCode }),
                           ex.ToString());
                return new List<VIEW_Salary>();
            }

            return myViewSalary;
        }
    }
}
